﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using SmartSpace.Data;
using SmartSpace.Core;
using SmartSpace.Data.AutoInput;

namespace SmartSpace.Workflow
{
    public class WorkflowService : IWorkflowService
    {
        private IWorkflowFactory _contextFactory;
        private ICoreService _coreService;
        private IDataService _dataService;

        public WorkflowService(IWorkflowFactory contextFactory, ICoreService coreService, IDataService dataService)
        {
            _contextFactory = contextFactory;
            _coreService = coreService;
            _dataService = dataService;
        }

        #region metadata

        public PagedList<WorkflowMetadata> FindWorkflows(int start, int limit)
        {
            using (WorkflowContext context = _contextFactory.Get())
            {
                List<WorkflowMetadata> list = context.Set<WorkflowMetadata>()
                    .Include("Entity")
                    .Include("Entity.Properties")
                    .Include("Activities")
                    .Include("Activities.Events")
                    .Include("Activities.Rights")
                    .Include("Activities.Rights.FieldRights")
                    .Include("Activities.Rights.FieldRights.Property")
                    .OrderByDescending(p => p.Caption)
                    .Skip(start)
                    .Take(limit)
                    .ToList();
                PagedList<WorkflowMetadata> pagedList = new PagedList<WorkflowMetadata>();
                foreach (WorkflowMetadata item in list)
                {
                    pagedList.Add(item);
                }
                pagedList.Start = start;
                pagedList.Limit = limit;
                pagedList.Total = context.Set<WorkflowMetadata>().Count();

                return pagedList;
            }
        }

        public WorkflowMetadata FindWorkflow(Guid id)
        {
            using (WorkflowContext context = _contextFactory.Get())
            {
                return context.Set<WorkflowMetadata>()
                    .Include("Entity")
                    .Include("Entity.Properties")
                    .Include("Entity.Properties.Type")
                    .Include("Activities")
                    .Include("Activities.Events")
                    .Include("Activities.Events.Type")
                    .Include("Activities.Events.Rights")
                    .Include("Activities.Events.Rights.Role")
                    .Include("Activities.Rights")
                    .Include("Activities.Rights.Role")
                    .Include("Activities.Rights.FieldRights")
                    .Include("Activities.Rights.FieldRights.Property")
                    .Where(p => p.Id == id)
                    .FirstOrDefault();
            }
        }

        public bool StoreWorkflow(WorkflowMetadata metadata)
        {
            using (WorkflowContext context = _contextFactory.Get())
            {
                metadata.Entity = null;

                foreach (ActivityMetadata activity in metadata.Activities)
                {
                    activity.Workflow = null;

                    if (activity.Events != null)
                    {
                        foreach (EventMetadata @event in activity.Events)
                        {
                            @event.FormActivity = null;
                            @event.ToActivity = null;
                            @event.Type = null;

                            foreach (var eventRight in @event.Rights)
                            {
                                eventRight.Event = null;
                                eventRight.Role = null;
                            }
                        }
                    }

                    if (activity.Rights != null)
                    {
                        foreach (ActivityRight right in activity.Rights)
                        {
                            right.Activity = null;
                            right.Role = null;
                            if (right.FieldRights != null)
                            {
                                foreach (FieldRight fieldRight in right.FieldRights)
                                {
                                    fieldRight.Activity = null;
                                    fieldRight.Property = null;
                                }
                            }
                        }
                    }
                }

                if (context.Set<WorkflowMetadata>()
                    .Where(p => p.Id == metadata.Id)
                    .Select(p => new { p.Id })
                    .FirstOrDefault() == null)
                {
                    context.Set<WorkflowMetadata>().Add(metadata);
                }
                else
                {
                    OnStoreActivities(metadata, context);
                    context.Entry(metadata).State = System.Data.Entity.EntityState.Modified;
                }

                context.SaveChanges();
                return true;
            }
        }

        public bool StoreDiagram(WorkflowDiagram diagram)
        {
            using (WorkflowContext context = _contextFactory.Get())
            {
                if (context.Set<WorkflowDiagram>()
                    .Where(p => p.Id == diagram.Id)
                    .Select(p => new { p.Id })
                    .FirstOrDefault() == null)
                {
                    context.Set<WorkflowDiagram>().Add(diagram);
                }
                else
                {
                    context.Entry(diagram).State = System.Data.Entity.EntityState.Modified;
                }

                context.SaveChanges();
                return true;
            }
        }

        public WorkflowDiagram FindDiagram(Guid id)
        {
            using (WorkflowContext context = _contextFactory.Get())
            {
                return context.Set<WorkflowDiagram>()
                    .Where(p => p.Id == id)
                    .FirstOrDefault();
            }
        }

        private void OnStoreActivities(WorkflowMetadata metadata, WorkflowContext context)
        {
            List<ActivityMetadata> activities = context.Set<ActivityMetadata>()
                .Where(p => p.WorkflowId == metadata.Id)
                .ToList();

            foreach (ActivityMetadata item in metadata.Activities)
            {
                bool isExist = false;
                foreach (ActivityMetadata activity in activities)
                {
                    if (item.Id == activity.Id)
                    {
                        isExist = true;
                        break;
                    }
                }

                if (!isExist)
                {
                    context.Set<ActivityMetadata>().Add(item);
                }
            }

            foreach (ActivityMetadata activity in activities)
            {
                ActivityMetadata newActivity = null;
                bool isExist = false;
                foreach (ActivityMetadata item in metadata.Activities)
                {
                    if (item.Id == activity.Id)
                    {
                        isExist = true;
                        newActivity = item;
                        break;
                    }
                }
                if (isExist)
                {
                    // 更新已有的activity
                    context.Entry(activity).State = System.Data.Entity.EntityState.Detached;

                    //this.OnStoreView(newActivity, context);
                    this.OnStoreEvents(newActivity, context);
                    this.OnStoreRights(newActivity, context);

                    // 更新activity的视图信息
                    context.Entry(newActivity).State = System.Data.Entity.EntityState.Modified;
                }
                else
                {
                    context.Set<ActivityMetadata>().Remove(activity);
                }
            }
        }

        //private void OnStoreView(ActivityMetadata activity, WorkflowContext context)
        //{
        //    List<FieldMetadata> fields = context.Set<FieldMetadata>()
        //        .Where(p => p.ViewId == activity.ModuleView.Id)
        //        .ToList();

        //    foreach (FieldMetadata field in fields)
        //    {
        //        FieldMetadata newField = null;
        //        bool isExist = false;
        //        foreach (FieldMetadata item in activity.ModuleView.Fields)
        //        {
        //            if (item.Id == field.Id)
        //            {
        //                isExist = true;
        //                newField = item;
        //                break;
        //            }
        //        }
        //        if (isExist)
        //        {
        //            // 更新已有的activity
        //            context.Entry(field).State = System.Data.Entity.EntityState.Detached;
        //            // 更新activity的视图信息
        //            context.Entry(newField).State = System.Data.Entity.EntityState.Modified;
        //        }
        //    }

        //    foreach (FieldMetadata item in activity.ModuleView.Fields)
        //    {
        //        bool isExist = false;
        //        foreach (FieldMetadata field in fields)
        //        {
        //            if (item.Id == field.Id)
        //            {
        //                isExist = true;
        //                break;
        //            }
        //        }

        //        if (!isExist)
        //        {
        //            context.Set<FieldMetadata>().Add(item);
        //        }
        //    }
        //}

        private void OnStoreEvents(ActivityMetadata activity, WorkflowContext context)
        {
            List<EventMetadata> events = context.Set<EventMetadata>()
                .Where(p => p.FormActivityId == activity.Id)
                .ToList();

            foreach (EventMetadata @event in events)
            {
                EventMetadata newEvent = null;
                bool isExist = false;
                foreach (EventMetadata item in activity.Events)
                {
                    if (item.Id == @event.Id)
                    {
                        isExist = true;
                        newEvent = item;
                        break;
                    }
                }
                if (isExist)
                {
                    context.Entry(@event).State = System.Data.Entity.EntityState.Detached;

                    OnStoreEventRights(newEvent, context);
                    context.Entry(newEvent).State = System.Data.Entity.EntityState.Modified;
                }
            }

            foreach (EventMetadata item in activity.Events)
            {
                bool isExist = false;
                foreach (EventMetadata @event in events)
                {
                    if (item.Id == @event.Id)
                    {
                        isExist = true;
                        break;
                    }
                }

                if (!isExist)
                {
                    context.Set<EventMetadata>().Add(item);
                }
            }
        }

        private void OnStoreRights(ActivityMetadata activity, WorkflowContext context)
        {
            List<ActivityRight> rights = context.Set<ActivityRight>()
                .Where(p => p.ActivityId == activity.Id)
                .ToList();

            foreach (ActivityRight item in activity.Rights)
            {
                bool isExist = false;
                foreach (ActivityRight right in rights)
                {
                    if (item.Id == right.Id)
                    {
                        isExist = true;
                        break;
                    }
                }

                if (!isExist)
                {
                    item.Activity = null;
                    context.Set<ActivityRight>().Add(item);
                }
            }

            foreach (ActivityRight right in rights)
            {
                ActivityRight existRight = null;
                bool isExist = false;
                foreach (ActivityRight item in activity.Rights)
                {
                    if (item.Id == right.Id)
                    {
                        isExist = true;
                        existRight = item;
                        break;
                    }
                }
                if (isExist)
                {
                    OnStoreFieldRights(existRight, context);

                    context.Entry(right).State = System.Data.Entity.EntityState.Detached;
                    existRight.Activity = null;
                    context.Entry(existRight).State = System.Data.Entity.EntityState.Modified;
                }
            }

        }

        private void OnStoreFieldRights(ActivityRight activityRight, WorkflowContext context)
        {
            List<FieldRight> rights = context.Set<FieldRight>()
                .Where(p => p.ActivityRightId == activityRight.Id)
                .ToList();

            foreach (FieldRight right in rights)
            {
                FieldRight existRight = null;
                bool isExist = false;
                foreach (FieldRight item in activityRight.FieldRights)
                {
                    if (item.Id == right.Id)
                    {
                        isExist = true;
                        existRight = item;
                        break;
                    }
                }
                if (isExist)
                {
                    context.Entry(right).State = System.Data.Entity.EntityState.Detached;
                    existRight.Activity = null;
                    existRight.Property = null;
                    existRight.ActivityRight = null;
                    context.Entry(existRight).State = System.Data.Entity.EntityState.Modified;
                }
            }

            foreach (FieldRight item in activityRight.FieldRights)
            {
                bool isExist = false;
                foreach (FieldRight right in rights)
                {
                    if (item.Id == right.Id)
                    {
                        isExist = true;
                        break;
                    }
                }

                if (!isExist)
                {
                    item.Activity = null;
                    item.Property = null;
                    context.Set<FieldRight>().Add(item);
                }
            }
        }

        private void OnStoreEventRights(EventMetadata @event, WorkflowContext context)
        {
            List<EventRight> rights = context.Set<EventRight>()
                .Where(p => p.EventId == @event.Id)
                .ToList();

            foreach (EventRight right in rights)
            {
                EventRight existRight = null;
                bool isExist = false;
                foreach (EventRight item in @event.Rights)
                {
                    if (item.Id == right.Id)
                    {
                        isExist = true;
                        existRight = item;
                        break;
                    }
                }

                if (isExist)
                {
                    // 更新
                    context.Entry(right).State = System.Data.Entity.EntityState.Detached;
                    existRight.Event = null;
                    existRight.Role = null;
                    context.Entry(existRight).State = System.Data.Entity.EntityState.Modified;
                }
                else
                {
                    // 删除
                    context.Entry(right).State = System.Data.Entity.EntityState.Deleted;
                }
            }

            foreach (EventRight item in @event.Rights)
            {
                bool isExist = false;
                foreach (EventRight right in rights)
                {
                    if (item.Id == right.Id)
                    {
                        isExist = true;
                        break;
                    }
                }

                if (!isExist)
                {
                    item.Event = null;
                    item.Role = null;
                    context.Set<EventRight>().Add(item);
                }
            }
        }

        public bool StoreEventType(EventType type)
        {
            using (WorkflowContext context = _contextFactory.Get())
            {
                if (context.Set<EventType>()
                    .Where(p => p.Id == type.Id)
                    .Select(p => new { p.Id })
                    .FirstOrDefault() == null)
                {
                    context.Set<EventType>().Add(type);
                }
                else
                {
                    context.Entry(type).State = System.Data.Entity.EntityState.Modified;
                }

                context.SaveChanges();
                return true;
            }
        }

        public List<EventType> FindEventTypes()
        {
            using (WorkflowContext context = _contextFactory.Get())
            {
                return context.Set<EventType>().ToList();
            }
        }

        #endregion

        /// <summary>
        /// 获取用户在流程特定步骤能访问的视图结构
        /// </summary>
        /// <param name="activity"></param>
        /// <param name="user"></param>
        /// <returns></returns>
        public ViewMetadata GetView(ActivityMetadata activity, WfViewType viewMode, WfState state, User user)
        {
            using (WorkflowContext context = _contextFactory.Get())
            {
                List<RelationRoleToUser> roles = context.Set<RelationRoleToUser>()
                    .Where(p => p.UserId == user.Id)
                    .ToList();

                ViewMetadata view = new ViewMetadata();
                view.Id = activity.Id;
                view.Caption = activity.Caption;
                view.Entity = activity.Workflow.Entity;
                view.Fields = new List<FieldMetadata>();

                // 用户具有的流程活动权限集合
                List<ActivityRight> hasRight = new List<ActivityRight>();

                #region 设置视图的访问权限,除当前操作角色外，其他人均是只读权限
                foreach (ActivityRight right in activity.Rights)
                {
                    foreach (RelationRoleToUser role in roles)
                    {
                        if (right.RoleId == role.RoleId)
                        {
                            hasRight.Add(right);

                            #region 有一个权限可以访问，那么就可以访问
                            view.CanVisit = view.CanVisit | right.IsAllowVisit;
                            view.CanModify = view.CanModify | right.IsAllowModify;
                            view.CanRemove = view.CanRemove | right.IsAllowRemove;
                            #endregion
                        }
                    }
                }
                #endregion

                if (hasRight.Count == 0)
                {
                    throw new Exception("没有访问Activity的权限!");
                }

                // 设置字段的可访问权限
                foreach (ActivityRight right in hasRight)
                {
                    foreach (FieldRight fieldRight in right.FieldRights)
                    {
                        FieldMetadata existField = null;
                        bool canVisit = true;
                        bool canModify = false;

                        if (fieldRight.Property.IsIdentity)
                        {
                            canVisit = fieldRight.IsAllowVisit;
                            canModify = fieldRight.IsAllowModify;
                        }
                        else if (viewMode == WfViewType.Detail)
                        {
                            if (!fieldRight.IsAllowVisit && !fieldRight.IsAllowModify)
                            {
                                continue;
                            }
                            canVisit = fieldRight.IsAllowVisit;
                            canModify = fieldRight.IsAllowModify;
                        }
                        else
                        {
                            if (!fieldRight.IsList)
                            {
                                continue;
                            }
                        }

                        foreach (var item in view.Fields)
                        {
                            if (item.PropertyId == fieldRight.PropertyId)
                            {
                                existField = item;
                                break;
                            }
                        }
                        if (existField == null)
                        {
                            FieldMetadata field = new FieldMetadata();
                            field.Property = fieldRight.Property;
                            field.PropertyId = fieldRight.PropertyId;
                            field.OrderIndex = fieldRight.Property.OrderIndex;
                            field.CanVisit = canVisit;
                            field.CanModify = canModify;

                            view.Fields.Add(field);
                        }
                        else
                        {
                            existField.CanVisit = existField.CanVisit | canVisit;
                            existField.CanModify = existField.CanModify | canModify;
                        }
                    }
                }

                view.Fields.Sort(new FieldMetadataComparer());

                return view;
            }
        }

        public List<WorkflowUser> GetEventReceivers(EventMetadata @event, User user)
        {
            using (WorkflowContext context = _contextFactory.Get())
            {
                List<WorkflowUser> operators = new List<WorkflowUser>();
                foreach (ActivityRight item in @event.ToActivity.Rights)
                {
                    Role role = _coreService.GetRole(item.RoleId);
                    List<User> users = _coreService.GetContainsUsers(role);
                    foreach (User userItem in users)
                    {
                        WorkflowUser op = new WorkflowUser();
                        op.Id = userItem.Id;
                        op.Account = userItem.Account;
                        op.Name = userItem.Name;
                        op.RoleId = item.RoleId;
                        op.RoleName = role.Caption;
                        operators.Add(op);
                    }
                }
                return operators;
            }
        }

        public DataInstance Save(ViewMetadata view, DataInstance data, User user)
        {
            return _dataService.Store(view, data, user);
        }

        public List<EventMetadata> GetEvents(ActivityMetadata activity, DataInstance data, User user)
        {
            List<EventMetadata> events = new List<EventMetadata>();

            List<EventMetadata> activityEvents = activity.Events;
            List<Role> roles = _coreService.GetAssignedRoles(user);
            foreach (var item in activityEvents)
            {
                bool hasRight = false;
                foreach (var eventRight in item.Rights)
                {
                    foreach (var userRole in roles)
                    {
                        if (eventRight.RoleId == userRole.Id)
                        {
                            hasRight = true;
                            break;
                        }
                    }

                    if (hasRight)
                    {
                        break;
                    }
                }

                if (hasRight)
                {
                    events.Add(item);
                }
            }

            return events;
        }

        public PagedList<DataInstance> GetDatas(
            WorkflowMetadata workflow, 
            ActivityMetadata activity, 
            WfViewType viewMode,
            WfState state,
            User user, 
            int start, 
            int limit)
        {
            using (WorkflowContext context = _contextFactory.Get())
            {
                PagedList<DataInstance> list = new PagedList<DataInstance>();
                list.Start = start;
                list.Limit = limit;

                ViewMetadata view = GetView(activity, viewMode, state,user);

                context.Database.Connection.Open();
                System.Data.Common.DbCommand command = context.Database.Connection.CreateCommand();
                List<System.Data.Common.DbParameter> parameters;
                string sql = Util.WfDbScriptUtil.GetPagedListScript(
                    workflow,
                    activity,
                    view,
                    viewMode,
                    state,
                    user,
                    start,
                    limit,
                    command,
                    out parameters);

                command.CommandText = sql;
                command.CommandType = System.Data.CommandType.Text;
                command.Parameters.AddRange(parameters.ToArray());
                System.Data.Common.DbDataReader reader = command.ExecuteReader();
                while (reader.Read())
                {
                    // 获取数据
                    DataInstance item = new DataInstance();
                    item.Fields = new List<FieldInstance>();

                    foreach (SmartSpace.Data.FieldMetadata field in view.Fields)
                    {
                        // 获取列表显示的字段，主键字段必须带上
                        if (field.CanVisit || field.Property.IsIdentity)
                        {
                            FieldInstance fieldData = new FieldInstance();
                            fieldData.OrderIndex = field.OrderIndex;
                            fieldData.Property = field.Property;

                            if (fieldData.Property.Type.IsComplex)
                            {
                                FieldInstance.SetData(fieldData, Convert.ToString(reader[field.Property.Name]), Convert.ToString(reader[field.Property.Name+"_text"]));
                            }
                            else
                            {
                                FieldInstance.SetData(fieldData, Convert.ToString(reader[field.Property.Name]));
                            }
                            item.Fields.Add(fieldData);
                        }
                    }

                    list.Add(item);
                }
                reader.Close();
                context.Database.Connection.Close();
                return list;
            }
        }

        public DataInstance GetData(ViewMetadata view, User user, Guid id)
        {
            return _dataService.GetData(view, user, id);
        }

        public ViewMetadata GetMetadata(ActivityMetadata activityMetadata)
        {
            throw new NotImplementedException();
        }

        /// <summary>
        /// 启动流程
        /// </summary>
        /// <param name="workflow"></param>
        /// <param name="activity"></param>
        /// <param name="data"></param>
        /// <param name="user"></param>
        /// <returns></returns>
        public WorkflowInstance Start(WorkflowMetadata workflow, ActivityMetadata activity, DataInstance data, User user)
        {
            using (WorkflowContext context = _contextFactory.Get())
            {
                // 创建流程实例
                WorkflowInstance instance = new WorkflowInstance();
                instance.Id = Guid.NewGuid();
                instance.WorkflowId = workflow.Id;
                instance.ActivityId = workflow.GetRoot().Id;
                instance.DataId = data.Id;
                instance.Caption = string.Format("{0}-实例", workflow.Caption);
                context.Set<WorkflowInstance>().Add(instance);

                context.SaveChanges();
                return instance;
            }
        }

        public WorkflowInstance GetInstance(Guid instanceId)
        {
            using (WorkflowContext context = _contextFactory.Get())
            {
                return context.Set<WorkflowInstance>()
                    .Where(p => p.DataId == instanceId)
                    .FirstOrDefault();
            }
        }

        public WorkflowInstance GetInstance(Guid workflowId, Guid dataId)
        {
            using (WorkflowContext context = _contextFactory.Get())
            {
                return context.Set<WorkflowInstance>()
                    .Where(p => p.WorkflowId == workflowId && p.DataId == dataId)
                    .SingleOrDefault();
            }
        }

        public WorkflowInstance GetInstance(DataInstance data)
        {
            using (WorkflowContext context = _contextFactory.Get())
            {
                Guid dataId = data.Id;
                return context.Set<WorkflowInstance>()
                    .Where(p => p.DataId == dataId)
                    .FirstOrDefault();
            }
        }

        public bool Drive(WorkflowMetadata workflow, ActivityMetadata activity, EventMetadata @event, Guid dataId, User sender, IEnumerable<Guid> receivers)
        {
            using (WorkflowContext context = _contextFactory.Get())
            {
                // 获取WorkflowInstance
                WorkflowInstance instance = context.Set<WorkflowInstance>()
                    .Where(p => p.DataId == dataId)
                    .FirstOrDefault();

                if (instance == null)
                {
                    // 启动流程实例
                    instance = new WorkflowInstance();
                    instance.Id = Guid.NewGuid();
                    instance.WorkflowId = workflow.Id;
                    instance.ActivityId = @event.ToActivityId;
                    instance.DataId = dataId;
                    instance.Caption = string.Format("{0}-实例", workflow.Caption);
                    context.Set<WorkflowInstance>().Add(instance);
                }
                else
                {
                    // 更新流程的当前活动
                    context.Entry(instance).State = System.Data.Entity.EntityState.Modified;
                    instance.Workflow = null;
                    instance.Activity = null;
                    instance.ActivityId = @event.ToActivityId;
                }

                // 解除掉 用户当前的处理的流程流转记录
                WorkflowDriveRecord oldDriveRecord = GetDriveRecord(context, instance, sender);

                List<WorkflowDriveRecord> newDRList;
                IWorkflowDriveEvent wfDriveEvent = DriveEventFactory.Get(@event.Type.Name);
                if (wfDriveEvent == null)
                {
                    throw new Exception("未发现事件的处理实现!");
                }

                WorkflowDriveRecord newDriveRecord = wfDriveEvent.Drive(
                     instance,
                     workflow,
                     activity,
                     @event,
                     oldDriveRecord,
                     dataId,
                     sender,
                     receivers);

                if (oldDriveRecord != null)
                {
                    oldDriveRecord.IsActivated = false;
                    context.Entry(oldDriveRecord).State = System.Data.Entity.EntityState.Modified;
                }
                if (newDriveRecord != null)
                {
                    context.Set<WorkflowDriveRecord>().Add(newDriveRecord);
                }

                if (context.SaveChanges() > 0)
                {
                    return true;
                }
                return false;

                // 创建流程任务
                //Task task = new Task(
                //    string.Format("任务:{0}", instance.Caption),
                //    instance.Id,
                //    sender.Id,
                //    receiver.Id);
                //if (this._taskService.Create(task))
                //{
                //    context.SaveChanges();
                //}
            }
        }

        public bool Drive(WorkflowInstance instance, EventMetadata @event, DataInstance data, User sender, User receiver)
        {
            using (WorkflowContext context = _contextFactory.Get())
            {
                // 更新流程的当前活动
                context.Entry(instance).State = System.Data.Entity.EntityState.Modified;
                instance.Workflow = null;
                instance.Activity = null;
                instance.ActivityId = @event.ToActivityId;

                // 解除掉用户当前的处理的流程流转记录
                WorkflowDriveRecord oldDriveRecord = context.Set<WorkflowDriveRecord>()
                    .Where(p => p.InstanceId == instance.Id 
                        && p.ReceiverId == instance.DataId
                        && p.IsActivated == true)
                    .SingleOrDefault();
                if (oldDriveRecord != null)
                {
                    oldDriveRecord.IsActivated = false;
                    context.Entry(oldDriveRecord).State = System.Data.Entity.EntityState.Modified;
                }

                // 创建流程流转记录
                WorkflowDriveRecord driveRecord = new WorkflowDriveRecord();
                driveRecord.Id = Guid.NewGuid();
                driveRecord.InstanceId = instance.Id;
                driveRecord.WorkflowId = instance.WorkflowId;
                driveRecord.ActivityId = @event.ToActivityId;
                driveRecord.SenderId = sender.Id;
                driveRecord.ReceiverId = receiver.Id;
                driveRecord.DrivedDate = DateTime.Now;
                driveRecord.RecordId = data.Id;
                driveRecord.IsActivated = true;
                context.Set<WorkflowDriveRecord>().Add(driveRecord);

                if (context.SaveChanges() > 0)
                {
                    return true;
                }
                return false;

                // 创建流程任务
                //Task task = new Task(
                //    string.Format("任务:{0}", instance.Caption),
                //    instance.Id,
                //    sender.Id,
                //    receiver.Id);
                //if (this._taskService.Create(task))
                //{
                //    context.SaveChanges();
                //}
            }
        }


        public PagedList<WorkflowInstance> GetJobs(User user, int start, int limit)
        {
            using (WorkflowContext context = _contextFactory.Get())
            {
                //return context.Set<WorkflowInstance>().ToList();
                    
            }
            return null;
        }

        public List<WfDriveLog> GetDriveHistories(WorkflowInstance instance)
        {
            using (WorkflowContext context = _contextFactory.Get())
            {
                List<WorkflowDriveRecord> records = context.Set<WorkflowDriveRecord>()
                    .Include("Children")
                    .Where(p=>p.InstanceId == instance.Id)
                    .OrderBy(p=>p.DrivedDate)
                    .ToList();

                List<WfDriveLog> logs = new List<WfDriveLog>();

                foreach (var record in records)
                {
                    logs.Add(ConvertRecordToLog(record, context));
                }

                return logs;
            }
        }

        private WfDriveLog ConvertRecordToLog(WorkflowDriveRecord record, WorkflowContext context)
        {
            WfDriveLog log = new WfDriveLog();
            log.FromId = record.SenderId;
            log.From = context.Set<User>().Where(p => p.Id == record.SenderId).FirstOrDefault().Name;

            log.ToId = record.ReceiverId;
            if (log.ToId != Guid.Empty)
            {
                if (record.ReceiverType == WfReceiverType.User)
                {
                    log.To = context.Set<User>().Where(p => p.Id == record.ReceiverId).FirstOrDefault().Name;
                }
                else
                {
                    log.To = context.Set<Org>().Where(p => p.Id == record.ReceiverId).FirstOrDefault().Caption;
                }
            }

            log.EventId = record.EventId;
            log.Event = context.Set<EventMetadata>().Where(p => p.Id == record.EventId).FirstOrDefault().Caption;

            log.ActivityId = record.ActivityId;
            log.Activity = context.Set<ActivityMetadata>().Where(p => p.Id == record.ActivityId).FirstOrDefault().Caption;

            log.DriveDate = record.DrivedDate;

            log.IsActivated = record.IsActivated;

            if (record.Children != null)
            {
                log.Items = new List<WfDriveLog>();
                foreach (var item in record.Children)
                {
                    log.Items.Add(ConvertRecordToLog(item, context));
                }
            }
            return log;
        }

        /// <summary>
        /// 获取用户操作时的当前步骤
        /// </summary>
        /// <param name="context"></param>
        /// <param name="instance"></param>
        /// <param name="user"></param>
        /// <returns></returns>
        private WorkflowDriveRecord GetDriveRecord(WorkflowContext context,WorkflowInstance instance, User user)
        {
            WorkflowDriveRecord driveRecord = context.Set<WorkflowDriveRecord>()
                .Include("Parent")
                .Where(p => p.InstanceId == instance.Id
                    && p.ReceiverId == user.Id
                    && p.ReceiverType.Code == WfReceiverType.User.Code
                    && p.IsActivated == true)
                .SingleOrDefault();

            if (driveRecord != null)
            {
                return driveRecord;
            }
            driveRecord = context.Set<WorkflowDriveRecord>()
                .Include("Parent")
                .Join(context.Set<OrgMember>().Where(r => r.UserId == user.Id),
                        p => p.ReceiverId,
                        v => v.OrgId,
                        (p, v) => p)
                .Where(p => p.InstanceId == instance.Id
                    && p.ReceiverType.Code != WfReceiverType.User.Code
                    && p.IsActivated == true)
                .SingleOrDefault();

            return driveRecord;
        }
    }
}
